
local raw = ...

local getmetatable, setmetatable = raw.getmetatable, raw.setmetatable
local pcall = pcall
local getfenv,setfenv = raw.getfenv, raw.setfenv
local error = error

local function constant(value)
	return function()  return value;  end
end

local mouse_meta do

	local mouse_getters = {
		x = raw.get_x;
		y = raw.get_y;
		getposition = constant(raw.get_position);
		confined = raw.get_confined;
		visible = raw.get_visible;
		onscreen = raw.get_onscreen;
	}
	
	local mouse_setters = {
		confined = raw.set_confined;
		visible = raw.set_visible;
	}

	mouse_meta = {
		__index = function(self, key)
			local getter = mouse_getters[key]
			if getter then
				return getter(self)
			end
			error('unrecognised field of mouse struct',2)
		end;
		__newindex = function(self, key, value)
			local setter = mouse_setters[key]
			if setter then
				return setter(self, value)
			end
			if mouse_getters[key] then
				error('attempt to set read-only field "' .. key .. '"', 2)
			end
			error('unrecognised field of mouse struct',2)
		end;
	}

end

local button_meta do
	
	local button_getters = {
		down = raw.button_get_down;
		struck = raw.button_get_struck;
		released = raw.button_get_released;
	}
	
	button_meta = {
		__index = function(self, key)
			local getter = button_getters[key]
			if getter then
				return getter(self)
			end
			error('unrecognised field of mouse button struct',2)
		end;
		__newindex = function()
			error('attempt to modify read-only mouse button struct',2)
		end;
	}
	
end

return setmetatable({
	left = setmetatable(raw.create_button(0), button_meta);
	middle = setmetatable(raw.create_button(1), button_meta);
	right = setmetatable(raw.create_button(2), button_meta);
}, mouse_meta)
